#pragma once

#include <iostream>
#include <sys/types.h>          
#include <sys/socket.h>
#include "Log.hpp"
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include "InetAddr.hpp"


const static int defaultfd = -1;

using namespace std;


class UdpServer
{
    public:
    UdpServer(uint16_t port)
    :_socketfd(defaultfd)
    ,_port(port)
    ,_isrunning(false)
    {}

    void InitServer()
    {
        EnableScreen();
        //1.创建udp socket套接字
        _socketfd = socket(AF_INET,SOCK_DGRAM,0);
        if(_socketfd<0)
        {
            Log(FATAL,"socket error: %s ,errno:%d\n",strerror(errno),errno);
            exit(-1);
        }
        Log(INFO,"socket create success,socketfd:%d\n",_socketfd);

        //2.填充struct sockaddr_in
        struct sockaddr_in local;
        
        //把local空间初始化为零
        bzero(&local,sizeof(local));
        local.sin_family = AF_INET;
        local.sin_port =  htons(_port);//主机序列-->网络序列
        local.sin_addr.s_addr = INADDR_ANY;//0.0.0.0
       
        //3.绑定IP和Port
        int n = bind(_socketfd,(struct sockaddr*)&local,sizeof(local));
        if(n<0)
        {
            Log(FATAL,"socket bind error: %s ,errno:%d\n",strerror(errno),errno);
            exit(-2);
        }
        Log(INFO,"socket bind successs\n");
    }

    void Start()
    {
        _isrunning = true;
        while(1)
        {
            sleep(1);
            char buffer[1024];
            struct sockaddr_in peer;
            socklen_t len = sizeof(peer); 
            //                        期望长度            输出型参数(想要知道是谁发的)
            ssize_t n = recvfrom(_socketfd,buffer,sizeof(buffer),0,(struct sockaddr*)&peer,&len);
            if(n>0)
            {
                buffer[n] = 0;
                InetAddr addr(peer);
                Log(DEBUG,"Get message:%s ------form:[%s:%d]\n",buffer,addr.Ip().c_str(),addr.Port());
                //把消息发回去
                sendto(_socketfd,buffer,sizeof(buffer),0,(struct sockaddr*)&peer,len);
            }

        }
        _isrunning = false;
    }


    ~UdpServer()
    {

    }


    private:
        int _socketfd;
        //IP地址可以写成0，这样就可以接受所有的Ip
        uint16_t _port;//端口号
        bool _isrunning;//是否运行中
};
